﻿using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;  // Esta clase contiene los métodos para controlar los recursos de audio del juego.
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;  // Esta clase contiene los métodos para controlar los periféricos de entrada.
using Microsoft.Xna.Framework.Media;
using _2D; // Usaremos las clases creadas en la libreria 2D
using System.Xml;
using System.Collections;

namespace LaunchDeath
{
    /// <summary>
    /// Clase que representa al juego.
    /// </summary>
    public class Game1 : Microsoft.Xna.Framework.Game
    {
        #region "Variables Globales"

        // Instancias de objetos para el manejo de gráficos.
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch1;

        // Instancia del objeto video para el manejo del video intro del juego.
        _2D.Video videointro;

        // Instancia del objeto Menu para la creación del Menú principal del juego.
        _2D.Menu menuprincipal;

        // Instancia del objeto Menu para usarlo para crear la pantalla de ranking.
        _2D.Menu menuranking;

        // Instancia del objeto Ranking para la inserción de puntuación de los jugadores.
        _2D.Ranking rankingjugadores;

        XmlDocument FicheroXML;

        // Definimos una HashTable para los Scores.
        Hashtable Scores;

        // Estructura necesaria para recorrer el hastable de Scores
        struct InfoCampusero
        {
            public string NickCampusero;
            public string PuntuacionCampusero;
        }

        InfoCampusero CampuseroStruct = new InfoCampusero();

        #endregion

        #region "Procedimiento GAME1"

        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";
        }

        #endregion

        #region "Procedimiento INITIALIZE"

        /// <summary>
        /// Este método permite al juego realizar cualquier inicialización que necesite antes
        /// de que el juego se inicie. Aquí es donde se puede llamar a cualquier servicio que
        /// necesite y cargar contenido no gráfico.
        /// </summary>
        protected override void Initialize()
        {
            // Tamaño de ventana personalizado.
            graphics.PreferredBackBufferHeight = 600;
            graphics.PreferredBackBufferWidth = 800;
            graphics.ApplyChanges();

            //menuprincipal = new _2D.Menu();
            //menuprincipal.Initialize();

            menuranking = new _2D.Menu();
            menuranking.Initialize();

            rankingjugadores = new _2D.Ranking();

            base.Initialize();
        }

        #endregion

        #region "Procedimiento LOADCONTENT y UNLOADCONTENT"

        /// <summary>
        /// Este proceso se llama inmediatamente después del método INITIALIZE.
        /// Se lanza una única vez y se debe utilizar para cargar los contenidos del juego.
        /// </summary>
        protected override void LoadContent()
        {
            // Este objeto está en XNA especialmente creado paLra manejar texturas y sprites. Sus instrucciones
            // generalmente se ejecutan en la GPU de la tarjeta gráfica. Se suele inicializar en el LoadContent y usar en el Draw.
            spriteBatch1 = new SpriteBatch(GraphicsDevice);

            // Cargamos el Video para la intro.
            //videointro.Load(Content, "Video/Intro");
            //videointro = new _2D.Video();
            //videointro.Load(Content, "Video/Intro");

            // Vamos a preparar la carga del menú principal
            //menuprincipal.Load(Content, "Sprites/FondoPrincipal", "Texto/Jokerman");

            // Vamos a preparar la carga del menú para mostrar el ranking
            menuranking.Load(Content, "Sprites/FondoPrincipal", "Texto/Jokerman");

            FicheroXML = new XmlDocument();
            FicheroXML.Load(@"../../../Ranking/Ranking.xml");
            rankingjugadores.Load(Content, FicheroXML);
            //rankingjugadores.Leerxmlranking();
            //rankingjugadores.Nuevonodoxmlranking(@"../../../Ranking/Ranking.xml", "MIGUEL", "3", "567");

            // Cargamos el objeto para el tema del Ranking
            Scores = new System.Collections.Hashtable();
            Scores = rankingjugadores.AlmacenPuntos;
        }

        /// <summary>
        /// Este procedimiento se lanza una única vez cuando se ejecuta el juego, se utiliza para descargar contenidos del juego.
        /// </summary>
        protected override void UnloadContent()
        {
            // Añade aquí código para descargar contenido del juego.
        }

        #endregion

        #region "Procedimiento UPDATE"

        /// <summary>
        /// Este procedimiento es invocado por el motor de XNA y permite controlar el estado del juego en cada instante
        /// de tiempo, para ello el método se lanza 60 veces por segundo permitiendo comprobar colisiones, acciones de
        /// los controles, reproducir audio, etc.
        /// </summary>
        /// <param name="gameTime">Proporciona los datos del juego en un momento de tiempo concreto.</param>
        protected override void Update(GameTime gameTime)
        {
            // Para controlar los eventos del teclado creamos una instancia de su clase.
            KeyboardState teclas = Keyboard.GetState();

            // Comprobamos si se pulsa la tecla esc para salir del juego.
            if (teclas.IsKeyDown(Keys.Escape))
            {
                this.Exit();
            }

            //videointro.Update();

            base.Update(gameTime);
        }

        #endregion

        #region "Procedimiento DRAW"

        /// <summary>
        /// Este método está especialmente pensado para encargarse de cargar los gráficos para pintar las cosas
        /// del juego. Hay que evitar poner en este método todo aquello que no sea para pintar la escena.
        /// Las instrucciones de este método se envian a la GPU gráfica.
        /// </summary>
        /// <param name="gameTime">Proporciona los datos del juego en un momento de tiempo concreto.</param>
        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.Black);

            spriteBatch1.Begin();
            //videointro.Draw(spriteBatch1);
            //menuprincipal.Draw(spriteBatch1);

            menuranking.Drawbasescore(spriteBatch1);

            // Recorremos el hastable
            foreach (DictionaryEntry item in Scores)
            {
                menuranking.Drawranking(spriteBatch1, CampuseroStruct.NickCampusero, item.Key.ToString(), CampuseroStruct.PuntuacionCampusero);
                CampuseroStruct = item.Value.GetType;
            }

            spriteBatch1.End();

            base.Draw(gameTime);
        }

        #endregion
    }
}